home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Text / WASTE / WASTE 1.1.2 Distribution / Demo Source / WEDemoFiles.p < prev    next >
Encoding:
Text File  |  1995-10-12  |  7.1 KB  |  303 lines  |  [TEXT/CWIE]

  1. unit WEDemoFiles;
  2.  
  3. { WASTE DEMO PROJECT: }
  4. { File Handling }
  5.  
  6. { Copyright © 1993-1995 Marco Piovanelli }
  7. { All Rights Reserved }
  8.  
  9. interface
  10.     uses
  11.         WEDemoIntf;
  12.  
  13.     function ReadTextFile (pFileSpec: FSSpecPtr;
  14.                                     we: WEReference): OSErr;
  15.     function WriteTextFile (pFileSpec: FSSpecPtr;
  16.                                     we: WEReference): OSErr;
  17.     function TranslateDrag (theDrag: DragReference;
  18.                                     theItem: ItemReference;
  19.                                     requestedType: FlavorType;
  20.                                     dataHandle: Handle): OSErr;
  21.  
  22. implementation
  23.  
  24.     function ReadTextFile (pFileSpec: FSSpecPtr;
  25.                                     we: WEReference): OSErr;
  26.         var
  27.             dataForkRefNum, resForkRefNum: Integer;
  28.             hText, hStyles, hSoup: Handle;
  29.             textSize: Size;
  30.  
  31.         procedure CleanUp;
  32.         begin
  33.             ForgetHandle(hText);
  34.             ForgetHandle(hStyles);
  35.             ForgetHandle(hSoup);
  36.  
  37.             if (dataForkRefNum > 0) then
  38.                 begin
  39.                     if (FSClose(dataForkRefNum) <> noErr) then
  40.                         ;
  41.                     dataForkRefNum := 0;
  42.                 end;
  43.  
  44.             if (resForkRefNum > 0) then
  45.                 begin
  46.                     CloseResFile(resForkRefNum);
  47.                     resForkRefNum := 0;
  48.                 end;
  49.         end;  { CleanUp }
  50.  
  51.         procedure CheckErr (err: OSErr);
  52.         begin
  53.             if (err <> noErr) then
  54.                 begin
  55.                     ReadTextFile := err;
  56.                     CleanUp;
  57.                     Exit(ReadTextFile);
  58.                 end;
  59.         end;  { CheckErr }
  60.  
  61.     begin
  62.         ReadTextFile := noErr;
  63.         dataForkRefNum := 0;
  64.         resForkRefNum := 0;
  65.         hText := nil;
  66.         hStyles := nil;
  67.         hSoup := nil;
  68.  
  69. { open the data fork with read-only permission }
  70.         CheckErr(FSpOpenDF(pFileSpec^, fsRdPerm, dataForkRefNum));
  71.  
  72. { get data fork size }
  73.         CheckErr(GetEOF(dataForkRefNum, textSize));
  74.  
  75. { try to allocate a handle that large; use temporary memory if available }
  76.         CheckErr(NewHandleTemp(textSize, hText));
  77.  
  78. { read in the text }
  79.         CheckErr(FSRead(dataForkRefNum, textSize, hText^));
  80.  
  81. { see if the file has a resource fork }
  82.         resForkRefNum := FSpOpenResFile(pFileSpec^, fsRdPerm);
  83.         if (resForkRefNum > 0) then
  84.             begin
  85.  
  86. { look for a style scrap resource (get the first one; the resource ID doesn't matter) }
  87.                 hStyles := Get1IndResource(kTypeStyles, 1);
  88.                 if (hStyles <> nil) then
  89.                     DetachResource(hStyles);
  90.  
  91. { look for a soup resource as well }
  92.                 hSoup := Get1IndResource(kTypeSoup, 1);
  93.                 if (hSoup <> nil) then
  94.                     DetachResource(hSoup);
  95.             end;
  96.  
  97. { insert the text into the WE record }
  98.         HLock(hText);
  99.         CheckErr(WEInsert(hText^, textSize, StScrpHandle(hStyles), hSoup, we));
  100.  
  101. { set the insertion point at the beginning of the text }
  102.         WESetSelection(0, 0, we);
  103.  
  104. { reset the WE instance modification count }
  105.         WEResetModCount(we);
  106.  
  107. { clean up and exit }
  108.         CleanUp;
  109.  
  110.     end;  { ReadTextFile }
  111.  
  112.     function WriteTextFile (pFileSpec: FSSpecPtr;
  113.                                     we: WEReference): OSErr;
  114.         var
  115.             dataForkRefNum, resForkRefNum: Integer;
  116.             hText, hStyles, hSoup: Handle;
  117.             fileInfo: FInfo;
  118.             textSize: Size;
  119.             replacing: Boolean;
  120.             err: OSErr;
  121.  
  122.         procedure CleanUp;
  123.         begin
  124.             ForgetResource(hStyles);
  125.             ForgetResource(hSoup);
  126.  
  127.             if (dataForkRefNum > 0) then
  128.                 begin
  129.                     if (FSClose(dataForkRefNum) <> noErr) then
  130.                         ;
  131.                     dataForkRefNum := 0;
  132.                 end;
  133.  
  134.             if (resForkRefNum > 0) then
  135.                 begin
  136.                     CloseResFile(resForkRefNum);
  137.                     resForkRefNum := 0;
  138.                 end;
  139.  
  140.         end;  { CleanUp }
  141.  
  142.         procedure CheckErr (err: OSErr);
  143.         begin
  144.             if (err <> noErr) then
  145.                 begin
  146.                     WriteTextFile := err;
  147.                     ErrorAlert(err);
  148.                     CleanUp;
  149.                     Exit(WriteTextFile);
  150.                 end;
  151.         end;  { CheckErr }
  152.  
  153.     begin
  154.         WriteTextFile := noErr;
  155.         dataForkRefNum := 0;
  156.         resForkRefNum := 0;
  157.         hText := nil;
  158.         hStyles := nil;
  159.         hSoup := nil;
  160.  
  161. { are we replacing an existing file? }
  162.         err := FSpGetFInfo(pFileSpec^, fileInfo);
  163.         if (err = noErr) then
  164.             replacing := true
  165.         else if (err = fnfErr) then
  166.             replacing := false
  167.         else
  168.             CheckErr(err);
  169.  
  170. { delete existing file, if any }
  171.         if (replacing) then
  172.             CheckErr(FSpDelete(pFileSpec^));
  173.  
  174. { create a new file }
  175.         FSpCreateResFile(pFileSpec^, kAppSignature, kTypeText, 0);
  176.         CheckErr(ResError);
  177.  
  178. { if replacing an old file, copy the old file information }
  179.         if (replacing) then
  180.             CheckErr(FSpSetFInfo(pFileSpec^, fileInfo));
  181.  
  182. { open the data fork for writing }
  183.         CheckErr(FSpOpenDF(pFileSpec^, fsRdWrPerm, dataForkRefNum));
  184.  
  185. { get the text handle from the WE instance }
  186. { WEGetText returns the original handle, not a copy, so don't dispose of it! }
  187.         hText := WEGetText(we);
  188.         textSize := GetHandleSize(hText);
  189.  
  190. { write the text }
  191.         CheckErr(FSWrite(dataForkRefNum, textSize, hText^));
  192.  
  193. { open the resource file for writing }
  194.         resForkRefNum := FSpOpenResFile(pFileSpec^, fsRdWrPerm);
  195.         CheckErr(ResError);
  196.  
  197. { allocate temporary handles to hold the style scrap and the soup }
  198.         CheckErr(NewHandleTemp(0, hStyles));
  199.         CheckErr(NewHandleTemp(0, hSoup));
  200.  
  201. { create the style scrap and the soup }
  202.         CheckErr(WECopyRange(0, maxLongInt, nil, StScrpHandle(hStyles), hSoup, we));
  203.  
  204. { make them resource handles }
  205.         AddResource(hStyles, kTypeStyles, 128, '');
  206.         CheckErr(ResError);
  207.         AddResource(hSoup, kTypeSoup, 128, '');
  208.         CheckErr(ResError);
  209.  
  210. { write them to the resource file }
  211.         WriteResource(hStyles);
  212.         CheckErr(ResError);
  213.         WriteResource(hSoup);
  214.         CheckErr(ResError);
  215.  
  216. { "clean" this document by resetting the WE instance modification count }
  217.         WEResetModCount(we);
  218.  
  219. { clean up }
  220.         CleanUp;
  221.  
  222.     end;  { WriteTextFile }
  223.  
  224.     function TranslateDrag (theDrag: DragReference;
  225.                                     theItem: ItemReference;
  226.                                     requestedType: FlavorType;
  227.                                     dataHandle: Handle): OSErr;
  228.  
  229. { this simple routine is meant to give an idea of how the drag translation hook ('xdrg') }
  230. { is supposed to work -- in the real world I should probably handle styled text files, }
  231. { PICT files and maybe other fancier file types here: }
  232. { that is left as an exercise for the reader }
  233.  
  234.         var
  235.             numFlavors: Integer;
  236.             theType: FlavorType;
  237.             hfs: HFSFlavor;
  238.             refNum: Integer;
  239.             dataSize: Size;
  240.  
  241.         procedure CleanUp;
  242.         begin
  243.             if (refNum <> 0) then
  244.                 begin
  245.                     if (FSClose(refNum) <> noErr) then
  246.                         ;
  247.                     refNum := 0;
  248.                 end;
  249.         end;  { CleanUp }
  250.  
  251.         procedure CheckErr (err: OSErr);
  252.         begin
  253.             if (err <> noErr) then
  254.                 begin
  255.                     TranslateDrag := err;
  256.                     CleanUp;
  257.                     Exit(TranslateDrag);
  258.                 end;
  259.         end;  { CheckErr }
  260.  
  261.     begin
  262.         TranslateDrag := badDragFlavorErr;        { assume failure }
  263.         refNum := 0;
  264.  
  265. { we'll try to translate HFS objects to TEXT, so make sure that is the requested type }
  266.         if (requestedType <> kTypeText) then
  267.             Exit(TranslateDrag);
  268.  
  269. { see if this drag item is a TEXT file }
  270.         dataSize := SizeOf(hfs);
  271.         if (CountDragItemFlavors(theDrag, theItem, numFlavors) = noErr) then
  272.             if (numFlavors = 1) then
  273.                 if (GetFlavorType(theDrag, theItem, 1, theType) = noErr) then
  274.                     if (theType = flavorTypeHFS) then
  275.                         if (GetFlavorData(theDrag, theItem, theType, @hfs, dataSize, 0) = noErr) then
  276.                             if (hfs.fileType = kTypeText) then
  277.                                 begin
  278.                                     TranslateDrag := noErr;        { assume success }
  279.  
  280. { if dataHandle is NIL, we're finished }
  281.                                     if (dataHandle = nil) then
  282.                                         Exit(TranslateDrag);
  283.  
  284. { open the file for reading }
  285.                                     CheckErr(FSpOpenDF(hfs.fileSpec, fsRdPerm, refNum));
  286.  
  287. { get file size }
  288.                                     CheckErr(GetEOF(refNum, dataSize));
  289.  
  290. { resize the data handle }
  291.                                     SetHandleSize(dataHandle, dataSize);
  292.                                     CheckErr(MemError);
  293.  
  294. { read the file }
  295.                                     CheckErr(FSRead(refNum, dataSize, dataHandle^));
  296.                                 end;
  297.  
  298. { clean up }
  299.         CleanUp;
  300.  
  301.     end;  { TranslateDrag }
  302.  
  303. end.